package com.ptkc.core.esearch.repos;

import com.ptkc.core.esearch.model.Order;
import com.ptkc.utils.ESUtil;
import org.elasticsearch.action.DocWriteResponse;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkRequestBuilder;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.VersionType;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.metrics.min.Min;
import org.elasticsearch.search.aggregations.metrics.min.MinAggregationBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Component;

import java.io.IOException;

/**
 * @author: Mr.Jiao
 * @date: 2018年09月30日
 */
@Component
public class OrderRepository  {

    private RestHighLevelClient restHighLevelClient;

    private final String INDEX = "runfast_order";

    private final String TYPE = "order";

    private ESUtil esUtil = null;

    public OrderRepository(RestHighLevelClient restHighLevelClient){
        this.restHighLevelClient = restHighLevelClient;
        this.esUtil = new ESUtil(restHighLevelClient);
    }


    public boolean save(Order order) throws IOException {
        if(order != null) {
            //转换登陆方式
            if(order.getAppOrwx() != null){
                //微信
                if(order.getAppOrwx().equals(0)){
                    //微信小程序
                    order.setLoginOn(2);
                }else if(order.getAppOrwx().equals(1)){
                    //APP
                    order.setLoginOn(1);
                }else{
                    order.setLoginOn(order.getAppOrwx());
                }
            }
            DocWriteResponse response = this.esUtil.save(INDEX, TYPE, String.valueOf(order.getId()),order);
            if(response.status() == RestStatus.OK || response.status() == RestStatus.CREATED){
                if(response.status() == RestStatus.CREATED){
                    this.setNewUserOrder(order.getId(), order.getUserId(), order.getAgentId());
                }
                return true;
            }
        }
        return false;
    }

    private void setNewUserOrder(Integer orderId, Integer userId, Integer agentId) throws IOException {
        boolean isUserFirst = OrderRepository.this.isFirst(orderId, userId, null);
        Order order = new Order();
        if(isUserFirst){
            order.setNewUserOrder(1);
        }else if(OrderRepository.this.isFirst(orderId, userId, agentId)){
            order.setNewUserOrder(2);
        }else{
            order.setNewUserOrder(0);
        }
        this.esUtil.updateSelective(INDEX, TYPE, String.valueOf(orderId), order);
    }

    public boolean delete(Order order) throws IOException {
        if(order != null) {
            DeleteRequest deleteRequest = new DeleteRequest(INDEX, TYPE, String.valueOf(order.getId()));
            DeleteResponse response = restHighLevelClient.delete(deleteRequest);
            if(response.status() == RestStatus.OK){
                return true;
            }
        }
        return false;
    }

    private boolean isFirst(int orderId, int userId, Integer agentId) {
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        SearchRequest searchRequest = new SearchRequest();
        MinAggregationBuilder field = AggregationBuilders.min("min_id").field("id");
        sourceBuilder.aggregation(field);
        BoolQueryBuilder builder = QueryBuilders.boolQuery();
        builder.must(QueryBuilders.termQuery("userId", userId));
        if (agentId != null) {
            builder.must(QueryBuilders.termQuery("agentId", agentId));
        }
        builder.mustNot(QueryBuilders.termQuery("id", orderId));
        builder.must(QueryBuilders.rangeQuery("status").from(0, true).to(8,true));
        sourceBuilder.query(builder).from(0).size(0);
        searchRequest.source(sourceBuilder).indices(INDEX).types(TYPE);
        SearchResponse response = null;
        try {
            response = restHighLevelClient.search(searchRequest);
        } catch (IOException e) {
            return false;
        }
        RestStatus status = response.status();
        if(status == RestStatus.OK) {
            Aggregations agg = response.getAggregations();
            Min min = agg.get("min_id");
            //新用户下单
            if ("Infinity".equals(min.getValueAsString())) {
                return true;
            }
            return false;
        }
        return false;
    }


    public boolean updateScore(String orderId, Integer score) throws IOException {
        Order order = new Order();
        order.setScore(score);
        if(this.esUtil.updateSelective(INDEX, TYPE, orderId, order)){
            return true;
        }
        return false;
    }

}
